package com.yabushan.activiti.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.yabushan.activiti.domain.NextStepAndUser;
import com.yabushan.activiti.util.Constant;
import com.yabushan.activiti.util.ErrMsgType;
import com.yabushan.activiti.util.Utils;
import com.yabushan.system.domain.ServiceStepConf;
import com.yabushan.system.service.IServiceStepConfService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
public class ProcessInstanceServiceImpl implements ProcessInstanceService{
	@Autowired
	private EngineService engineService;

	@Autowired
	private IServiceStepConfService serviceStepConfService;

	@Override
	public ProcessInstance StartProcess(String userId, String businessId,
										String processDefinitionKey) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put(Constant.REQUEST_USER, userId);//流程规则定义的发起人的ID
		variables.put(Constant.BUSINESS_ID, businessId);//业务主键ID
		//使用流程定义的Key启动流程实例
		engineService.getIdentityService().setAuthenticatedUserId(userId);
		ProcessInstance pi = engineService.getRuntimeService()
				.startProcessInstanceByKey(processDefinitionKey,businessId,variables);
		return pi;
	}

	@Override
	public List<Task> queryMySingleTasks(String userId) {
		List<Task> list = engineService.getTaskService()
				.createTaskQuery().taskAssignee(userId)
				.orderByTaskCreateTime().asc()
				.list();
		return list;
	}

	@Override
	public List<Task> queryMyGroupTasks(String userId) {

		//	List<Task> list2 = engineService.getTaskService().createTaskQuery().taskCandidateUser("777").list();
		List<Task> list = engineService.getTaskService()
				.createTaskQuery()
				.taskCandidateUser(userId)
				.orderByTaskCreateTime().desc()
				.list();
		return list;
	}

	@Override
	public List<Task> getMyTasks(String userId) {
		List<Task> tasks = new ArrayList<Task>();
		tasks.addAll(queryMySingleTasks(userId));
		tasks.addAll(queryMyGroupTasks(userId));
		return tasks;

	}

	@Override
	public void claim(String taskId, String dealUser) {
		engineService.getTaskService().claim(taskId, dealUser);
	}

	@Override
	public void trunTask(String taskId, String dealUser) {
		engineService.getTaskService().setAssignee(taskId,dealUser);
	}

	@Override
	public ProcessInstance processInstanceStep(String processInstanceId) {
		ProcessInstance pi = engineService.getRuntimeService()
				.createProcessInstanceQuery()
				.processInstanceId(processInstanceId)
				.singleResult();
		return pi;
	}

	@Override
	public void completeTask(String taskId,String userId,String nextDealUser,String nextSeqFlow,String stepInfo) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("nextDealUser",nextDealUser);//流程中设置下一个审批人的占位符为：userName
		variables.put("message", nextSeqFlow);//设置下一步步骤
		//variables.put("opinion", requestMessage.getApproveOpinion());//保存流程实体
		engineService.getTaskService().setVariableLocal(taskId,Constant.STEP_INFO, stepInfo);
		//engineService.getTaskService().setVariable(requestMessage.getTaskId(), "message", requestMessage.getNextSeqFlow());
		claim(taskId,userId);
		engineService.getTaskService().complete(taskId, variables);

	}

	@Override
	public void changeAssigneeTask(String taskId, String dealUserId) {
		engineService.getTaskService().setAssignee(taskId, dealUserId);
	}

	@Override
	public List<IdentityLink> getIdentityLinks(String taskId) {
		List<IdentityLink> list = engineService.getTaskService()
				.getIdentityLinksForTask(taskId);
		return list;
	}
	@Override
	public List<NextStepAndUser> queryOutComeListByTaskId(String taskId) {
		NextStepAndUser nextStepAndUser =null;
		List<NextStepAndUser> list = new ArrayList<>();

		//1.使用任务ID，查询任务对象
		Task task = engineService.getTaskService().createTaskQuery()
				.taskId(taskId).singleResult();
		//2.获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		//3.查询processDefinitionEntity对象
		ProcessDefinitionEntity processDefinitionEntity=(ProcessDefinitionEntity) engineService.getRepositoryService()
				.getProcessDefinition(processDefinitionId);
		//使用任务对象task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		ProcessInstance pi= engineService.getRuntimeService().createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		//获取当前活动的id
		String activityId = pi.getActivityId();
		//获取当前的活动
		ActivityImpl activityImpl=processDefinitionEntity.findActivity(activityId);
		//获取当前活动完成后的连线的名称
		List<PvmTransition> pvmList =activityImpl.getOutgoingTransitions();
		if(pvmList!=null && pvmList.size()>0){
			for (PvmTransition pvmTransition : pvmList) {
				nextStepAndUser =new NextStepAndUser();
				String outLinkName =(String) pvmTransition.getProperty("name");
				Object stepName = pvmTransition.getDestination().getProperty("name");//获取名称
				nextStepAndUser.setOutLine(outLinkName);
				nextStepAndUser.setNextStep(stepName.toString());
				//获取环节办理人
				ServiceStepConf conf = new ServiceStepConf();
				conf.setProcdefId(task.getProcessDefinitionId());
				conf.setStepName(stepName.toString());
				List<ServiceStepConf> serviceStepConfs = serviceStepConfService.selectServiceStepConfList(conf);
				if(serviceStepConfs.size()>0){
					nextStepAndUser.setJumpStep(serviceStepConfs.get(0).getStepCode());
					nextStepAndUser.setNextUserId(serviceStepConfs.get(0).getDealUserId());
					nextStepAndUser.setNextUserName(serviceStepConfs.get(0).getDealUserName());
					nextStepAndUser.setNextUserRole(serviceStepConfs.get(0).getDealRoleName());
					nextStepAndUser.setNextUserRoleId(serviceStepConfs.get(0).getDealRoleId());
					nextStepAndUser.setNextDealType(serviceStepConfs.get(0).getDealType());
				}
				list.add(nextStepAndUser);
			}
		}
		return list;
	}

	@Override
	public Task queryTaskInfo(String taskId) {
		Task task=engineService.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		return task;
	}

	@Override
	public PvmActivity queryOutComeNameByTaskId(String taskId, String nextStepName) {
		PvmActivity destPa = null;
		// 1.使用任务ID，查询任务对象
		Task task = engineService.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		// 2.获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		// 3.查询processDefinitionEntity对象
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) engineService.getRepositoryService().getProcessDefinition(processDefinitionId);
		// 使用任务对象task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		// 使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		ProcessInstance pi = engineService.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		// 获取当前活动的id
		String activityId = pi.getActivityId();
		// 获取当前的活动
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
		// 获取当前活动完成后的连线的名称
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
		if (pvmList != null && pvmList.size() > 0) {
			for (PvmTransition pvmTransition : pvmList) {
				String name = (String) pvmTransition.getProperty("name");
				if (StringUtils.isNotBlank(name) && name.equals(nextStepName)) {
					destPa = pvmTransition.getDestination();
					break;
				}
			}
		}
		return destPa;
	}

	@Override
	public void completeTask(String taskId,String userId,String nextDealUser,String nextNodeName,String nextSeqFlow,String stepInfo) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("nextDealUser",nextDealUser);//流程中设置下一个审批人的占位符为：userName
		variables.put("message", nextSeqFlow);//设置下一步步骤
		if(StringUtils.isNoneEmpty(nextNodeName)) {
			variables.put("nextNodeName", nextNodeName);//设置下一步任务名称
		}
		engineService.getCommentService().addCommentInfo(taskId,null,nextNodeName);
		//variables.put("opinion", requestMessage.getApproveOpinion());//保存流程实体
		engineService.getTaskService().setVariableLocal(taskId,Constant.STEP_INFO, stepInfo);
		//engineService.getTaskService().setVariable(requestMessage.getTaskId(), "message", requestMessage.getNextSeqFlow());
		claim(taskId,userId);
		engineService.getTaskService().complete(taskId, variables);

	}

	@Override
	public List<Task> queryMySingleTasks(String userId,String processInstanceId) {
		TaskQuery taskQuery = engineService.getTaskService().createTaskQuery();
		taskQuery.taskAssignee(userId);
		if(StringUtils.isNotEmpty(processInstanceId)) {
			taskQuery.processInstanceId(processInstanceId);
		}
		List<Task> list = taskQuery.orderByTaskCreateTime().asc().list();
		return list;
	}

	@Override
	public void completeTaskWithParams(String taskId, String userId, String nextDealUser, String nextSeqFlow, String stepInfo,String params) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("nextDealUser",nextDealUser);//流程中设置下一个审批人的占位符为：userName
		variables.put("message", nextSeqFlow);//设置下一步步骤
		engineService.getTaskService().setVariableLocal(taskId,Constant.STEP_INFO, stepInfo);
		//保存自定义参数
		if(Utils.IsNotEmpty(params)) {
			Map maps = (Map)JSON.parse(params);
			variables.putAll(maps);
		}
		claim(taskId,userId);
		engineService.getTaskService().complete(taskId, variables);
	}

	@Override
	public ProcessInstance starkFormTask(String processDefinitionId,String requestUserId, String businessKey, String variables) {
		ProcessInstance processInstance=null;
		Map request = JSON.parseObject(variables);
		request.put(Constant.REQUEST_USER,requestUserId);//流程规则定义的发起人的ID
		request.put(Constant.BUSINESS_ID, businessKey);//业务主键ID
		ProcessDefinition pd = engineService.getRepositoryService().createProcessDefinitionQuery()
				.processDefinitionKey(processDefinitionId).latestVersion()
				.singleResult();

		engineService.getIdentityService().setAuthenticatedUserId(requestUserId);
		processInstance = engineService.getFormService().submitStartFormData(pd.getId(), businessKey, request);
		return  processInstance;
	}

	@Override
	@Transactional
	public void completeFormTask(String taskId,String userId, Map formVariables, Map taskVariables,Map excutionVarialbes) {
		engineService.getFormService().saveFormData(taskId,formVariables);
		engineService.getTaskService().setVariablesLocal(taskId,taskVariables);
		Task task = engineService.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		engineService.getRuntimeService().setVariables(task.getExecutionId(),excutionVarialbes);
		claim(taskId,userId);
		engineService.getTaskService().complete(taskId, taskVariables);

	}

	@Override
	public void saveTask(String taskId, Map formVariables, Map taskVariables) {
		engineService.getFormService().saveFormData(taskId,formVariables);
		engineService.getTaskService().setVariablesLocal(taskId,taskVariables);

	}

	@Override
	public NextStepAndUser getNextStepAndUser(Task task) {
		ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)engineService.getRepositoryService()).getDeployedProcessDefinition(task.getProcessDefinitionId());

		List<ActivityImpl> activitiList = def.getActivities();  //rs是指RepositoryService的实例
		String excId = task.getExecutionId();
		ExecutionEntity execution = (ExecutionEntity) engineService.getRuntimeService().createExecutionQuery().executionId(excId).singleResult();
		String activitiId = execution.getActivityId();

		for(ActivityImpl activityImpl:activitiList){
			String id = activityImpl.getId();
			if(activitiId.equals(id)){
				System.out.println("当前任务："+activityImpl.getProperty("name")); //输出某个节点的某种属性
				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();//获取从某个节点出来的所有线路
				for(PvmTransition tr:outTransitions){
					PvmActivity ac = tr.getDestination(); //获取线路的终点节点
					System.out.println("下一步任务任务："+ac.getProperty("name"));
				}
				break;
			}
		}
		return null;
	}

	@Override
	public ProcessInstance StartProcessWithParams(String userId, String businessId, String processDefinitionKey,
												  String params) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put(Constant.REQUEST_USER, userId);//流程规则定义的发起人的ID
		variables.put(Constant.BUSINESS_ID, businessId);//业务主键ID
		//保存自定义参数
		if(Utils.IsNotEmpty(params)) {
			Map maps = (Map)JSON.parse(params);
			variables.putAll(maps);
		}
		//使用流程定义的Key启动流程实例
		engineService.getIdentityService().setAuthenticatedUserId(userId);
		ProcessInstance pi = engineService.getRuntimeService()
				.startProcessInstanceByKey(processDefinitionKey,businessId,variables);
		return pi;
	}




}
